from typing import Optional
from urllib.parse import quote_plus

from .logger import log_event
from .config import Config

# Selenium imports are done lazily to allow environments without selenium to still run non-web actions
_driver = None


def _load_selenium():
    global webdriver, Options, By, WebDriverWait, EC
    from selenium import webdriver
    from selenium.webdriver.edge.options import Options
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.support import expected_conditions as EC
    return webdriver, Options, By, WebDriverWait, EC


def ensure_driver() -> Optional[object]:
    """Ensure an Edge WebDriver instance using Selenium Manager (Selenium >=4.6)."""
    global _driver
    if _driver is not None:
        return _driver
    try:
        webdriver, Options, *_ = _load_selenium()
        opts = Options()
        try:
            if getattr(Config, "BROWSER_HEADLESS", False):
                # new headless is more stable in recent Edge versions
                opts.add_argument("--headless=new")
        except Exception:
            pass
        opts.add_argument("--start-maximized")
        _driver = webdriver.Edge(options=opts)
        log_event("WEB_BROWSER_INIT", "Edge WebDriver initialized")
        return _driver
    except Exception as e:
        log_event("WEB_BROWSER_ERROR", f"init failed: {e}")
        return None


def close_driver():
    global _driver
    try:
        if _driver:
            _driver.quit()
            log_event("WEB_BROWSER_CLOSE", "Edge WebDriver closed")
    except Exception:
        pass
    finally:
        _driver = None


def search(query: str, engine: str = "baidu") -> bool:
    drv = ensure_driver()
    if not drv:
        return False
    try:
        q = quote_plus(query)
        url = (
            f"https://www.baidu.com/s?wd={q}" if engine.lower() == "baidu" else f"https://www.bing.com/search?q={q}"
        )
        drv.get(url)
        log_event("WEB_SEARCH", f"engine={engine}, query={query}")
        return True
    except Exception as e:
        log_event("WEB_SEARCH_ERROR", f"{e}")
        return False


def click_first_result(engine: str = "baidu", timeout: int = 10) -> bool:
    drv = ensure_driver()
    if not drv:
        return False
    try:
        _, _, By, WebDriverWait, EC = _load_selenium()
        wait = WebDriverWait(drv, timeout)
        try:
            if engine.lower() == "baidu":
                # Baidu result link selector (best-effort)
                elem = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "#content_left .t a, #content_left .result a")))
            else:
                # Bing result link selector (best-effort)
                elem = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "li.b_algo h2 a, .b_algo h2 a")))
            elem.click()
            log_event("WEB_CLICK_FIRST_RESULT", f"engine={engine}")
            return True
        except Exception:
            # fallback: click first anchor element
            elem = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "a")))
            elem.click()
            log_event("WEB_CLICK_FALLBACK", "clicked first anchor")
            return True
    except Exception as e:
        log_event("WEB_CLICK_ERROR", f"{e}")
        return False


def click_link_text(text: str, timeout: int = 10) -> bool:
    drv = ensure_driver()
    if not drv:
        return False
    try:
        _, _, By, WebDriverWait, EC = _load_selenium()
        wait = WebDriverWait(drv, timeout)
        try:
            elem = wait.until(EC.element_to_be_clickable((By.LINK_TEXT, text)))
            elem.click()
            log_event("WEB_CLICK_LINK_TEXT", f"text={text}")
            return True
        except Exception:
            elem = wait.until(EC.element_to_be_clickable((By.PARTIAL_LINK_TEXT, text)))
            elem.click()
            log_event("WEB_CLICK_PARTIAL_TEXT", f"text={text}")
            return True
    except Exception as e:
        log_event("WEB_CLICK_TEXT_ERROR", f"{e}")
        return False


def navigate(url: str) -> bool:
    drv = ensure_driver()
    if not drv:
        return False
    try:
        if not (url.startswith("http://") or url.startswith("https://")):
            url = "https://" + url
        drv.get(url)
        log_event("WEB_NAVIGATE", f"url={url}")
        return True
    except Exception as e:
        log_event("WEB_NAVIGATE_ERROR", f"{e}")
        return False